﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.IO.Ports;
using System.Windows.Forms;

namespace MapRoom
{
    class SerialPortControl
    {
        private static string serialBuffer;
        private static RobotScanDialog _myRobotScanDialog;
        private static MapModel _myMapModel;

        private static SerialPort _port;

        public static SerialPort port
        {
            get { return SerialPortControl._port; }
            set { SerialPortControl._port = value; }
        }

        private static bool _isScanning;

        public static bool isScanning
        {
            get { return SerialPortControl._isScanning; }
            set { SerialPortControl._isScanning = value; }
        }

        private static bool _stopScanning;

        public static bool stopScanning
        {
            get { return SerialPortControl._stopScanning; }
            set { SerialPortControl._stopScanning = value; }
        }

        private static Thread _scanThread;

        public static Thread scanThread
        {
            get { return _scanThread; }
            set { _scanThread = value; }
        }

        public static void startRobotScan( RobotScanDialog myRobotScanDialog,
            MapModel myMapModel )
        {
            if( isScanning )
            {
                return;
            }

            _myMapModel = myMapModel;
            _myRobotScanDialog = myRobotScanDialog;
            scanThread = new Thread( SerialPortControl.scanForRobots );    
            if (scanThread != null)
            {
                isScanning = true;           
                stopScanning = false;
                scanThread.Start();
            }
        }

        public static void stopRobotScan( )
        {
            stopScanning = true;
        }

        private static void scanForRobots( )
        {
            SerialPort scanPort;
            char [] buffer = null;
            string bufferString;
            int bytesToRead;

            foreach (string portName in SerialPort.GetPortNames())
            {
                //send request for robot ID
                scanPort = new SerialPort( portName, 19200 );//, 57600, Parity.None, 8, StopBits.One);

                if( stopScanning )
                {
                    // exit if the user wants to stop scanning
                    // do we need to do anything fancy with serial ports
                    // before stopping?
                    if( _myRobotScanDialog.Visible )
                    {
                        _myRobotScanDialog.closeForm();
                    }

                    isScanning = false;
                    return;
                }

                _myRobotScanDialog.setStatusLabel( portName );

                try
                {
                    scanPort.Open( );
                    scanPort.Write( "id" );
                    Thread.Sleep( 500 );
                    bytesToRead = scanPort.BytesToRead;
                    if (bytesToRead == 0)
                    {
                        scanPort.Close( );
                        continue;
                    }

                    buffer = new char[ bytesToRead ];
                    scanPort.Read( buffer, 0, bytesToRead );
                    bufferString = new String( buffer );
                    if( bufferString.Contains( "START" ) && bufferString.Contains( "STOP" ) )
                    {
                        _myRobotScanDialog.setStatusLabel( String.Format( "Discovered a robot on {0}.", portName ) );
                        if( _port != null && _port.IsOpen )
                        {
                            _port.Close( );
                        }
                        scanPort.DataReceived += new SerialDataReceivedEventHandler(serialDataReceived);
                        _port = scanPort;
                        Thread.Sleep( 500 );
                        break;
                    }
                    else
                    {
                        scanPort.Close( );
                        continue;
                    }
                }
                catch (Exception ex)
                {
                } 

            }

            if( _myRobotScanDialog.Visible )
            {
                _myRobotScanDialog.closeForm();
            }
            isScanning = false;
        }

        public static bool haveFoundRobot( )
        {
            if( _port == null )
            {
                return false;
            }

            return _port.IsOpen;
        }

        public static bool switchToPort( string portName )
        {
            SerialPort tempPort = new SerialPort( portName );
            try
            {
                tempPort.Open( );
                _port = tempPort;
            }
            catch( Exception ex )
            {
                return false;
            }

            return true;
        }

        private static void serialDataReceived( Object sender, SerialDataReceivedEventArgs e )
        {
            int bytesToRead = _port.BytesToRead;
            char [ ] buffer = null;
            buffer = new char[ bytesToRead ];
            _port.Read( buffer, 0, bytesToRead );
            string myString = new string( buffer );
            serialBuffer += myString;
            while( serialBuffer.Contains( "START" ) && serialBuffer.Contains( "STOP" ) )
            {
                XBeeMessage xBeeMessage = new XBeeMessage( );
                if( xBeeMessage.parseString( serialBuffer.Substring( serialBuffer.IndexOf( "START" ),
                    serialBuffer.IndexOf( "STOP" ) + 4 - serialBuffer.IndexOf( "START" ) ) ) )
                {
                    _myMapModel.updateMapModel( new MapModelUpdateData( xBeeMessage ) );
                }
                
                serialBuffer = serialBuffer.Substring( serialBuffer.IndexOf( "STOP" ) + 4 );
            }
        }
    }
}
